import { Ref, SetupContext, computed, ref } from "vue";
import BigNumber from "bignumber.js";
import { UseNumber } from "./types";
import { NumberRangeProps } from "../number-range.props";

export function useNumber(props: NumberRangeProps, context: SetupContext): UseNumber {
    const precision = computed(() => Number(props.precision) || 0);

    /**
     * 基于精度参数修改toFixed方法
     * @param value
     * @returns
     */
    function toFixed(value: BigNumber | number) {
        return value.toFixed(precision.value);
    }

    /**
     * 判断输入框中的值是否为空
     * @param val 输入值
     * @returns 返回是否时空值的判断结果
     */
    function isEmpty(value: string | number | undefined): boolean {
        return isNaN(value as number) || value === null || value === undefined || value === '';
    }

    /**
     * 最值校验
     * @param bn
     * @returns
     */
    function getValidNumberObject(numberObject: BigNumber): BigNumber {
        const maxValue = !isEmpty(props.max) ? new BigNumber(String(props.max), 10) : null;
        const minValue = !isEmpty(props.min) ? new BigNumber(String(props.min), 10) : null;
        const validNumberObject = (maxValue && numberObject.gt(maxValue)) ? maxValue :
            ((minValue && numberObject.lt(minValue)) ? minValue : numberObject);
        return validNumberObject;
    }

    /**
     * 获取实际数值
     * @param val
     * @returns
     */
    function getRealValue(value: any) {
        if (props.parser) {
            if (!isNaN(Number(value))) {
                return value;
            }
            return props.parser(value);
        }
        let numberObject = getValidNumberObject(new BigNumber(value, 10));
        if (numberObject.isNaN()) {
            if (props.canNull) {
                return null;
            }
            const minBigNum = new BigNumber('' + props.min, 10);
            const maxBigNum = new BigNumber('' + props.max, 10);
            if (!minBigNum.isNaN()) {
                numberObject = minBigNum;
            } else if (!maxBigNum.isNaN()) {
                numberObject = maxBigNum;
            } else {
                return 0;
            }
        }
        const fixedNumberString = toFixed(numberObject);
        return fixedNumberString;
    }

    return { getRealValue, isEmpty, precision, getValidNumberObject };
}
